﻿using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.Xml.Xsl;
using SharePointOfView.Diagnostics;
using SharePointOfView;
using SharePointOfView.SPReporting.Common;

namespace SharePointOfView.SPReporting
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://www.codeplex.com/SoVSPReporting/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class ReportHandler : IHttpHandler
    {
        #region IHttpHandler Members
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/xml";

            string output = "";
            int reportId = 0;

            if (context.Request.QueryString["rid"] != null)
            {
                if (!int.TryParse(context.Request.QueryString["rid"], out reportId))
                {
                    reportId = 0;
                }
                System.Diagnostics.Debug.Write(string.Format("Report Id : {0}", reportId), Globals.LogCategory);
            }

            if (reportId > 0)
            {
                var report = new Report(reportId);

                if (!string.IsNullOrEmpty(report.Source))
                {
                    System.Diagnostics.Debug.Write(string.Format("Report Name : {0}", report.Name), Globals.LogCategory);
                    System.Diagnostics.Debug.Write(string.Format("Report Chart Type : {0}", report.ChartType), Globals.LogCategory);
                    var args = new XsltArgumentList();
                    args.AddParam("report-name", "", report.Name);
                    //args.AddParam("report-chart-type", "", report.ChartType.ToString());
                    args.AddParam("report-date", "", DateTime.Now.ToString("s"));
                    args.AddExtensionObject("urn:report-extended-utilities", new XSLTExtensions());

                    if (report.Xml.Count == 1)
                    {
                        foreach (DateTime key in report.Xml.Keys)
                        {
                            output = SharePointOfView.Utilities.XSLT.XSLTransform(report.Xml[key], report.Xslt, args);
                        }
                    }
                    else
                    {
                        DataSet ds = null;
                        DateTime lastDate = DateTime.MinValue;
                        foreach (DateTime key in report.Xml.Keys)
                        {
                            if (key > lastDate) lastDate = key;
                        }
                        args.AddParam("report-last-date", "", lastDate.ToString("s"));

                        foreach (DateTime key in report.Xml.Keys)
                        {
                            args.RemoveParam("report-date", "");
                            args.AddParam("report-date", "", key.ToString("s"));
                            string bindableXml = SharePointOfView.Utilities.XSLT.XSLTransform(report.Xml[key], report.Xslt, args);

                            try
                            {
                                using (StringReader sr = new StringReader(bindableXml))
                                {
                                    if (ds == null)
                                    {
                                        ds = new DataSet();
                                        ds.ReadXml(sr);
                                        // Preserve unique Filter
                                        DataTable dtFilter = ds.Tables["Filter"];
                                        if (dtFilter != null)
                                        {
                                            dtFilter.PrimaryKey = new DataColumn[] { dtFilter.Columns["Name"] };
                                        }
                                    }
                                    else
                                    {
                                        using (DataSet ds2 = new DataSet())
                                        {
                                            ds2.ReadXml(sr);
                                            // Preserve unique Filter
                                            DataTable dtFilter = ds2.Tables["Filter"];
                                            if (dtFilter != null)
                                            {
                                                dtFilter.PrimaryKey = new DataColumn[] { dtFilter.Columns["Name"] };
                                            }

                                            ds.Merge(ds2);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Debug.Write(ex.Message);
                            }
                        }

                        if (ds != null)
                        {
                            output = ds.GetXml();
                            ds.Dispose();
                        }
                    }
                }
                else
                {
                    System.Diagnostics.Debug.Write("ERROR : Report Source is empty", Globals.LogCategory);
                    ULS.WriteError(string.Format("Report Source for Report {0} is empty", reportId), Globals.LogCategory);
                    output = string.Format("<Report><Error>{0}</Error></Report>", HttpUtility.HtmlEncode(report.Name));
                }
            }
            else
            {
                System.Diagnostics.Debug.Write("ERROR : No Report", Globals.LogCategory);
                ULS.WriteError(string.Format("No Report for ID : {0}", reportId), Globals.LogCategory);
                output = "<Report><Error>No report</Error></Report>";
            }

            context.Response.Write(output);
        }

        public bool IsReusable
        {
            get { return false; }
        }
        #endregion
    }
}